package rad.framework.uml2.classdiagram.edit.parts;

import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Property;

public class AssociationFigure extends PolylineConnectionEx {

	private IMapMode mapMode;

	public AssociationFigure(IMapMode mapMode, Association association) {
		this.mapMode = mapMode;

		// if both nav then no arrow
		if (!getFirstProperty(association).isNavigable()
				|| !getSecondProperty(association).isNavigable()) {
			if (getFirstProperty(association).isNavigable()) {
				setTargetDecoration(createArrow());
			}
			if (getSecondProperty(association).isNavigable()) {
				setSourceDecoration(createArrow());
			}
		}
		if (getFirstProperty(association).isComposite()) {
			setSourceDecoration(createDiamond());
		}
	}

	protected Property getFirstProperty(Association association) {
		if (association.getMemberEnds() != null
				&& association.getMemberEnds().size() > 0) {
			return (Property) association.getMemberEnds().get(0);
		}
		return null;
	}

	protected Property getSecondProperty(Association association) {
		if (association.getMemberEnds() != null
				&& association.getMemberEnds().size() > 1) {
			return (Property) association.getMemberEnds().get(1);
		}
		return null;
	}

	private org.eclipse.draw2d.PolygonDecoration createDiamond() {
		org.eclipse.draw2d.PolygonDecoration df = new org.eclipse.draw2d.PolygonDecoration();
		// dispatchNext?
		df.setFill(true);
		org.eclipse.draw2d.geometry.PointList pl = new org.eclipse.draw2d.geometry.PointList();
		pl.addPoint(-1, 1);
		pl.addPoint(0, 0);
		pl.addPoint(-1, -1);
		pl.addPoint(-2, 0);
		df.setTemplate(pl);
		df.setScale(mapMode.DPtoLP(9), mapMode.DPtoLP(5));

		return df;
	}

	private org.eclipse.draw2d.PolylineDecoration createArrow() {
		org.eclipse.draw2d.PolylineDecoration df = new org.eclipse.draw2d.PolylineDecoration();
		df.setScale(mapMode.DPtoLP(14), mapMode.DPtoLP(6));
		return df;
	}

}
